package imsdk

import (
	"encoding/json"
	"fmt"
	"longmen/server/config/global"
	"longmen/server/pkg/common/helper/http"
	"math/rand"
)

const (
	NOTIFY_START_LIVE  = "notify_live"
	NOTIFY_START_MATCH = "notify_match"
)

type OfflineMsgNats struct {
	OfflineArgs
	Condition
	User    []string `json:"user"`
	Title   string   `json:"title"`
	Content string   `json:"content"`
}

type OfflineMsg struct {
	FromAccount     string   `json:"From_Account"`
	ToAccount       []string `json:"To_Account,omitempty" `
	MsgLifeTime     int      `json:"MsgLifeTime"` //消息离线存储时间，单位秒，最多保存7天（604800秒）。默认为0，表示不离线存储，即只推在线用户
	MsgRandom       int32    `json:"MsgRandom"`
	Condition       `json:"Condition,omitempty"`
	MsgBody         []OfflineMsgBody `json:"MsgBody"`
	OfflinePushInfo `json:"OfflinePushInfo"`
}

// 发送离线消息的標籤過濾
// 帶入透過已存在標籤的過濾條件
type Condition struct {
	TagsAnd []string `json:"TagsAnd,omitempty"`
	TagsOr  []string `json:"TagsOr,omitempty"`
}

type OfflineMsgBody struct {
	MsgType    string            `json:"MsgType"`
	MsgContent OfflineMsgContent `json:"MsgContent"`
}

// im 离线消息體
type OfflineMsgContent struct {
	Data  string `json:"Data,omitempty"`
	Desc  string `json:"Desc,omitempty"`
	Ext   string `json:"Ext,omitempty"`
	Sound string `json:"Sound,omitempty"`
}

// im 离线消息體內的 自定義消息體
type OfflineArgs struct {
	RoomType  int32 `json:"type"`      // 0=打開app 1=跳至官方直播间 2=跳至主播直播间
	SportType int32 `json:"sportType"` // 1=足球 2=篮球
	RoomId    int32 `json:"id"`        // 房間id
}

// 離線訊息的相關設定
type OfflinePushInfo struct {
	PushFlag    int    `json:"PushFlag"`
	Desc        string `json:"Desc"`          // 自定义消息描述信息 - 放入 OfflineArgs 字符串
	Ext         string `json:"Ext,omitempty"` // 扩展字段
	Title       string `json:"Title"`         // 消息标题
	AndroidInfo `json:"AndroidInfo"`
	ApnsInfo    `json:"ApnsInfo"`
}

type AndroidInfo struct {
	//Sound string `json:"Sound"`
}

type ApnsInfo struct {
	//Sound     string `json:"Sound"`
	BadgeMode int    `json:"BadgeMode"` // 这个字段缺省或者为0表示需要计数，为1表示本条消息不需要计数，即右上角图标数字不增加。
	SubTitle  string `json:"SubTitle"`
	Image     string `json:"Image"`
}

func (o OfflineMsg) BroadcastOfflineAll() error {
	url := GetSdk().BuildRestfulUrl("/all_member_push/im_push")

	j, err := json.Marshal(o)
	if err != nil {
		global.Log.Errorf("BroadcastOfflineAll error: %v", err)
		return err
	}

	global.Log.Debugf("BroadcastOfflineAll Messege body: %s", string(j))
	result, err := http.HttpPost(url, string(j), connTimeoutMs, serveTimeoutMs, "application/json")
	if err != nil {
		global.Log.Errorf("Broadcast OfflineAll http request error: %v, result: %s", err, string(result))
		return err
	}
	global.Log.Debugf("Broadcast OfflineAll result: %s", string(result))

	resp := &SendImResponse{}
	err = json.Unmarshal(result, &resp)
	if err != nil {
		global.Log.Error("Broadcast OfflineMsgAll resp Unmarshal error: ", err)
		return err
	}
	if resp.ActionStatus == FailActionStatus {
		// 未开通全员推送功能 返回空
		if resp.ErrorCode == 90045 {
			return nil
		}
		global.Log.Error("Broadcast OfflineMsgAll resp error: ", err)
		return fmt.Errorf(resp.ErrorInfo)
	}

	return nil
}

// 批量單聊接口，大於500人分批發送
func (o OfflineMsg) BroadcastOffline() error {
	url := GetSdk().BuildRestfulUrl("/openim/batchsendmsg")

	users := o.ToAccount

	times := len(users) / 500
	if len(users)%500 != 0 {
		times++
	}
	for i := 0; i < times; i++ {
		if i == times-1 {
			o.ToAccount = users[i*500:]
		} else {
			o.ToAccount = users[i*500 : (i+1)*500]
		}

		j, err := json.Marshal(o)
		if err != nil {
			global.Log.Errorf("Broadcast OfflineMsg error: %v", err)
			return err
		}
		global.Log.Debugf("Broadcast OfflineMsg Messege body: %s", string(j))
		result, err := http.HttpPost(url, string(j), connTimeoutMs, serveTimeoutMs, "application/json")
		if err != nil {
			global.Log.Errorf("Broadcast OfflineMsg http request error: %v, result: %s", err, string(result))
			return err
		}
		global.Log.Debugf("Broadcast OfflineMsg result: %s", string(result))

		resp := &SendImResponse{}
		err = json.Unmarshal(result, &resp)
		if err != nil {
			global.Log.Error("Broadcast OfflineMsg resp Unmarshal error: ", err)
			return err
		}
		if resp.ActionStatus == FailActionStatus {
			global.Log.Error("Broadcast OfflineMsg resp error: ", resp.ErrorInfo)
			if resp.ErrorCode == 90012 { //收件人错误，不返回错误（返回错误的话，会在RabbitMQ重新入队）
				return nil
			}
			return fmt.Errorf(resp.ErrorInfo)
		}
		global.Log.Infof("Broadcast OfflineMsg Messege success : %s", string(j))
	}

	return nil
}

// 发送离线消息
// 本接口包含全员/属性/标签推送，默认每天最多调用100次，每两次推送间隔必须大于1s
// 為避免一秒內發送多條訊息，請使用 Nats chennal : IM_ALL_MEMBER_PUSH 發送全員訊息
func (o OfflineMsg) SendOfflineMsg(data OfflineArgs, condition Condition, user []string, title, body string) error {

	if (len(o.Condition.TagsOr) != 0 && len(user) != 0) || (len(o.Condition.TagsAnd) != 0 && len(user) != 0) {
		return fmt.Errorf("can not use tag-filter and specify user at meanwhile")
	}
	o.FromAccount = "admin"
	o.MsgLifeTime = 604800
	o.MsgRandom = rand.Int31()
	o.OfflinePushInfo.Title = title
	o.OfflinePushInfo.ApnsInfo.BadgeMode = 1
	o.ToAccount = user
	o.Condition = condition
	j, err := json.Marshal(data)
	if err != nil {
		global.Log.Errorf("SendOfflineMsg error: %v", err)
		return err
	}
	o.OfflinePushInfo.Desc = body
	o.OfflinePushInfo.Ext = string(j)
	o.MsgBody = append(o.MsgBody, OfflineMsgBody{
		MsgType: "TIMCustomElem",
		MsgContent: OfflineMsgContent{
			//Data: string(dataj),
			Data: "",
		},
	})
	if len(o.ToAccount) == 0 {
		return o.BroadcastOfflineAll()
	}

	return o.BroadcastOffline()
}

//
//func (o OfflineMsg) OfflineMsg() (*pb.OfflineMsgResp, error) {
//	fmt.Println("1111111")
//	if o.Title == "" && len(o.MsgBody) == 0 {
//		return &pb.OfflineMsgResp{Msg: "Title and OfflineMsg is require"}, fmt.Errorf("send offline msg error")
//	}
//	if (len(o.Condition.TagsOr) != 0 && len(o.ToAccount) != 0) || (len(o.Condition.TagsAnd) != 0 && len(o.ToAccount) != 0) {
//		return &pb.OfflineMsgResp{Msg: "Can not use tag-filter and specify user at meanwhile"}, fmt.Errorf("send offline msg error")
//	}
//	content := OfflineArgs{
//		RoomType:  o.JumpType,
//		SportType: o.SportType,
//		Id:        o.RoomId,
//		Msg:       o.OfflineMsg,
//	}
//
//	msg := &imsdk.GetSdk().OfflineMsg
//	msg.Title = o.Title
//	msg.ApnsInfo.SubTitle = o.AppSubTitle
//	msg.ApnsInfo.Image = o.AppImagePath
//	msg.OfflinePushInfo.Desc = *content
//	msg.MsgBody = append([]imsdk.OfflineMsgBody{}, imsdk.OfflineMsgBody{
//		MsgType: "TIMCustomElem",
//		MsgContent: imsdk.OfflineMsgContent{
//			Data: *content,
//		},
//	})
//
//	err := imsdk.GetSdk().SendOfflineMsg(o.IsAnd, o.Tags, o.SenderUid)
//	if err != nil {
//		return &pb.OfflineMsgResp{Msg: "send offline msg err"}, err
//	}
//	return &pb.OfflineMsgResp{Msg: "send offline msg success"}, nil
//}
